﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Text;
using WPFCABShell.Shell.Interface.Services.Options;
using Microsoft.Practices.CompositeUI;
using Microsoft.Practices.ObjectBuilder;
using Kent.Boogaart.HelperTrinity;

namespace WPFCABShell.$safeprojectname$.Options
{
	public class OptionsService : IOptionsService
	{
		private readonly WorkItem _workItem;

		[InjectionConstructor]
		public OptionsService([Dependency(NotPresentBehavior = NotPresentBehavior.Throw)] WorkItem workItem)
		{
			_workItem = workItem;
		}

		public IOptions Register(string targetSiteName, string name, Type paneType, string siteName)
		{
			ArgumentHelper.AssertNotNull(targetSiteName, "targetSiteName");
			ArgumentHelper.AssertNotNull(name, "name");
			ArgumentHelper.AssertNotNull(paneType, "paneType");
			ExceptionHelper.ThrowIf(!typeof(IOptionsPane).IsAssignableFrom(paneType), "PaneTypeDoesntImplementRequiredInterface", paneType.FullName, typeof(IOptionsPane).Name);

			IOptions options = CreateOptions(targetSiteName, name, paneType, siteName);

			//add the options to the target site
			_workItem.UIExtensionSites[targetSiteName].Add(options);

			//register new site if given
			if (siteName != null)
			{
				_workItem.UIExtensionSites.RegisterSite(siteName, options);
			}

			return options;
		}

		public void Unregister(IOptions options)
		{
			ArgumentHelper.AssertNotNull(options, "options");

			//remove the options from the extension site
			_workItem.UIExtensionSites[options.TargetSiteName].Remove(options);

			if (options.SiteName != null)
			{
				_workItem.UIExtensionSites.UnregisterSite(options.SiteName);
			}
		}

		protected virtual IOptions CreateOptions(string targetSiteName, string name, Type paneType, string siteName)
		{
			return new Options(targetSiteName, name, paneType, siteName);
		}

		#region Supporting Types

		private sealed class Options : System.Windows.Controls.TreeViewItem, IOptions
		{
			private readonly string _targetSiteName;
			private readonly string _name;
			private readonly Type _paneType;
			private readonly string _siteName;

			public string TargetSiteName
			{
				get
				{
					return _targetSiteName;
				}
			}

			public string Name
			{
				get
				{
					return _name;
				}
			}

			public Type PaneType
			{
				get
				{
					return _paneType;
				}
			}

			public string SiteName
			{
				get
				{
					return _siteName;
				}
			}

			public Options(string targetSiteName, string name, Type paneType, string siteName)
			{
				Debug.Assert(targetSiteName != null);
				Debug.Assert(name != null);
				Debug.Assert(paneType != null);

				_targetSiteName = targetSiteName;
				_name = name;
				_paneType = paneType;
				_siteName = siteName;

				Header = name;
			}
		}

		#endregion
	}
}
